# -*-coding:utf-8 -*-
__author__ = 'yulei'


import os
#用来设置该项目是以开发模式启动还是以生产环境启动
os.environ['Mobile3_PUSH_ANDROID_WORK_RUN_MODEL'] = "release"   #  开发:develop  生产:release

from datetime import datetime,timedelta
import time

from haigha.connection import Connection
from haigha.message import Message

from common import logTool
import pushmsg
import json
from common.dbTool import get_collection
import settings
import traceback

def re_save_msg_to_queue(msg):
    '''
    在发送异常时把消息重新保存到消息队列中
    :param msg:
    :return:
    '''

    try:

        connection = Connection(
            user='guest',
            password='guest',
            vhost='/',
            host=settings.RABBIT_HOST,
            heartbeat=None,
            debug=False)

        exchange_name = 'ex_mtd_bufa_v3'
        routing = 'rt_mtd_mobile_Android_bufa_v3'

        channel = connection.channel()

        channel.exchange.declare(exchange_name, 'direct', durable=True)
        channel.basic.publish(Message(msg, application_headers={}),exchange_name,routing)

    except Exception,ex:
        #print Exception,':',ex
        logTool.errorHandle()
    finally:
        if connection:
            connection.close()


def callback(message):

    try:

        #print " [x] Received ,call time %s" % (datetime.now())
        delivery_info = message.delivery_info
        channel = message.delivery_info['channel']
        msg = json.loads(str(message.body))
        #msg = dict(eval(str(message.body)))

        if msg:

            if msg.has_key('pushDate'):
                pubdate = msg['pushDate']
            elif msg.has_key('PushDate'):
                pubdate = msg['PushDate']

            current = datetime.now()
            t = time.strptime(pubdate,"%Y-%m-%d %H:%M:%S")
            pub=datetime(t[0],t[1],t[2],t[3],t[4],t[5])
            diff = current - pub
            if current < pub or diff.seconds < (3600*4):#判断信息的发布日期是否已经超过4小时
                hanlde(msg)

        #print " [x] Done"
        #消息确认就是当工作者完成任务后，会反馈给rabbitmq
        channel.basic.ack(delivery_info["delivery_tag"])
    except Exception, ex:
        #print Exception, ":", ex
        #print traceback.format_exc()
        channel.basic.ack(delivery_info["delivery_tag"])
        logTool.errorHandle()
        #re_save_msg_to_queue(str(message.body))
        re_save_msg_to_queue(json.dumps(msg))


def hanlde(push_msg_dict):
    '''

    :param push_msg_dict:
    :return:
    '''

    infotype = int(push_msg_dict.get('infotype','0')) #5:短讯  6:资讯
    cmd = push_msg_dict.get('cmd','all') #all:群推  single:单推
    list_push_data = []

    if infotype == 5:

        if cmd == 'all':

            ptypelist = [9]

            for ptype in ptypelist:
                cliendidList = get_clientid_of_sms(push_msg_dict,ptype)
                temp = {}
                if cliendidList:
                    temp['cliendids'] = cliendidList  # 群推 cliendids
                    temp['content'] = push_msg_dict['content']
                    temp['newsFrom'] = push_msg_dict['newsFrom']
                    temp['oid'] = push_msg_dict['oid']
                    temp['PType'] = ptype
                    temp['infotype'] = infotype
                    temp['pushDate'] = push_msg_dict['pushDate']
                    list_push_data.append(temp)

            push_msg_to_igetui_all(list_push_data)

        elif cmd == 'single':
            proudcttype = int(push_msg_dict.get('PType','9')) #该参数主要用于单推时用
            cliendidList = get_clientid_of_sms(push_msg_dict,proudcttype)
            temp = {}
            if cliendidList:
                temp['cliendid'] = cliendidList[0]  # 单推 cliendid
                temp['content'] = push_msg_dict['content']
                temp['newsFrom'] = push_msg_dict['newsFrom']
                temp['oid'] = push_msg_dict['oid']
                temp['PType'] = proudcttype
                temp['infotype'] = infotype
                temp['pushDate'] = push_msg_dict['pushDate']
                push_msg_to_igetui_single(temp)

    elif infotype == 6:

        if cmd == 'all':

            if int(push_msg_dict['IsPublicNews']) == 0:#收费信息

                ptypelist = [7,8,9]

                for ptype in ptypelist:

                    temp = {}
                    push_msg_dict['PType'] = ptype
                    cliendid_list = get_clientid_of_mobile(push_msg_dict)

                    if cliendid_list:
                        temp['cliendids'] = cliendid_list  # 群推 cliendids
                        temp['Title'] = push_msg_dict['Title']
                        temp['NewsFrom'] = push_msg_dict['NewsFrom']
                        temp['NewsKey'] = push_msg_dict['NewsKey']
                        temp['PType'] = push_msg_dict['PType']
                        temp['IsPublicNews'] = push_msg_dict['IsPublicNews']
                        temp['PushDate'] = push_msg_dict['PushDate']
                        temp['infotype'] = push_msg_dict['infotype']

                        list_push_data.append(temp)

                push_msg_to_igetui_all(list_push_data)

            else:#公共信息

                cliendidList = get_clientid_of_mobile(push_msg_dict)
                temp = {}
                if cliendidList:
                    temp['cliendids'] = cliendidList  # 群推 cliendids
                    temp['Title'] = push_msg_dict['Title']
                    temp['NewsFrom'] = push_msg_dict['NewsFrom']
                    temp['NewsKey'] = push_msg_dict['NewsKey']
                    temp['PType'] = push_msg_dict['PType']
                    temp['IsPublicNews'] = push_msg_dict['IsPublicNews']
                    temp['PushDate'] = push_msg_dict['PushDate']
                    temp['infotype'] = push_msg_dict['infotype']
                    list_push_data.append(temp)

                    push_msg_to_igetui_all(list_push_data)

        elif cmd == 'single':

            cliendidList = get_clientid_of_mobile(push_msg_dict)
            temp = {}
            if cliendidList:
                temp['cliendid'] = cliendidList[0]  # 单推 cliendid
                temp['Title'] = push_msg_dict['Title']
                temp['NewsFrom'] = push_msg_dict['NewsFrom']
                temp['NewsKey'] = push_msg_dict['NewsKey']
                temp['PType'] = push_msg_dict['PType']
                temp['IsPublicNews'] = push_msg_dict['IsPublicNews']
                temp['PushDate'] = push_msg_dict['PushDate']
                temp['infotype'] = push_msg_dict['infotype']
                temp['userid'] = push_msg_dict['uid']

                logTool.create_push_log(u'获取clientid成功，clientid={}'.format(temp['cliendid']), u'anroid_work_3.0',
                                        temp['PType'], temp['PushDate'], temp['userid'][0], temp['Title'], temp['NewsKey'])

                push_msg_to_igetui_single(temp)

    else:
        pass


def push_msg_to_igetui_all(para_list_msg):
    '''
    将要发送的信息发送给个推
    :param para_list_msg:
    :return:
    '''

    for msg in para_list_msg:
        pushmsg.push_message_to_list(msg)


def push_msg_to_igetui_single(msg_dict):
    '''
    将指定的信息发送给特定的用户
    :param msg_dict:
    :return:
    '''
    pushmsg.push_message_to_single(msg_dict)


def get_clientid_of_mobile(para_dict):
    '''
    获取用户的clientid
    :param para_dict:
    :return:
    '''

    device_collection = get_collection(settings.MONGO_DATA_DB_COLLECTION,settings.MONGO_DEVICE_COLLECTION)

    #收费信息或者是查询指定的用户
    if int(para_dict['IsPublicNews']) == 0 or para_dict['cmd'] == 'single':

        uid = para_dict['uid']

        if not uid:#如何是空列表，则返回
            return []

        con_dict_device={
            'producttype':para_dict['PType'],
            'devicetype':0,
            'userid':{'$in':uid},
            'clientid':{'$ne':''},
            #'version':{'$in':['3.0']}
            'version': {'$gte': '3.0'}
        }

    else:#公共信息

        con_dict_device={
            'producttype':para_dict['PType'],
            'devicetype':0,
            'clientid':{'$ne':''},
            #'version':{'$in':['3.0']}
            'version': {'$gte': '3.0'}
        }


    result_clientid = device_collection.find(con_dict_device,{'_id':0,'clientid':1})


    clientid_list = [item['clientid'] for item in result_clientid
                     if item['clientid'] !='(null)' and len(item['clientid']) == 32]

    return clientid_list


def get_clientid_of_sms(para_dict,ptype):
    '''
    获取用户的clientid
    :param para_dict:
    :param ptype:
    :return:
    '''

    device_collection = get_collection(settings.MONGO_DATA_DB_COLLECTION,settings.MONGO_DEVICE_COLLECTION)
    usernamelist = para_dict['userlist']
    if len(usernamelist) == 0:
        return []

    condictdevice={
        'producttype':ptype,
        'devicetype':0,
        'username':{'$in':usernamelist},
        'clientid':{'$ne':''},
        #'version':{'$in':['3.0']}
        'version': {'$gte': '3.0'}
    }

    result_clientid = device_collection.find(condictdevice,{'clientid':1,'_id':0,'version':1})

    clientid_list = [item['clientid'] for item in result_clientid
                     if item['clientid'] !='(null)' and len(item['clientid']) == 32]

    return clientid_list


def main():
    '''
    客户端-Android消费者
    :return:
    '''

    connection = None
    try:

        connection = Connection(
            user='guest',
            password='guest',
            vhost='/',
            host=settings.RABBIT_HOST,
            heartbeat=None,
            debug=False)

        channel = connection.channel()
        exchange_name = 'ex_mtd_mobile_v3'
        queue_name = "queue_mtd_mobile_Android_v3"
        routing = "rt_mtd_mobile_v3.#"

        #定义交换机，设置类型为topic
        channel.exchange.declare(exchange_name,'topic',durable=True)
        channel.queue.declare(queue_name, auto_delete=False,durable=True)
        channel.queue.bind(queue_name, exchange_name, routing)

        channel.basic.qos(prefetch_count=1)#公平调度(Fair dispatch)
        channel.basic.consume(queue_name, callback, no_ack=False)

        #print ' [*] Waiting for messages. To exit press CTRL+C'
        while not channel.closed:
            connection.read_frames()
    except Exception, ex:
        #print Exception, ":", ex
        logTool.errorHandle()
    finally:
        if connection:
            #channel.stop_consuming()
            connection.close()

if __name__ == '__main__':
    main()